TypeScript์ ๋ชจ๋ ์ ์ธ์ ๋ง์คํฐํ์ธ์: ์ธ๋ถ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ํ ์ฐ๋น์ธํธ ๋ชจ๋๊ณผ ๋ฒ์ฉ ํ์ ์ ์ํ ์ ์ญ ํ์ ์ ์. ๊ธ๋ก๋ฒ ํ์์ ์ฝ๋ ํ์ง๊ณผ ์ ์ง๋ณด์์ฑ์ ํฅ์์ํค์ธ์.
TypeScript ๋ชจ๋ ์ ์ธ: ๊ฐ๋ ฅํ ๊ธ๋ก๋ฒ ๊ฐ๋ฐ์ ์ํ ์ฐ๋น์ธํธ ๋ชจ๋๊ณผ ์ ์ญ ํ์ ์ ์ ํ์
ํ๋ ์ํํธ์จ์ด ๊ฐ๋ฐ์ ๊ด๋ํ๊ณ ์ํธ ์ฐ๊ฒฐ๋ ์ธ์์์ ํ์ ์ข ์ข ๋๋ฅ์ ๊ฐ๋ก์ง๋ฌ ํ๋ก์ ํธ๋ฅผ ์ํํ๋ฉฐ, ์ํํ ํตํฉ, ๋์ ์ ์ง๋ณด์์ฑ, ์์ธก ๊ฐ๋ฅํ ๋์์ ํ์๋ก ํฉ๋๋ค. TypeScript๋ ์ด๋ฌํ ๋ชฉํ๋ฅผ ๋ฌ์ฑํ๊ธฐ ์ํ ์ค์ํ ๋๊ตฌ๋ก ๋ถ์ํ์ผ๋ฉฐ, JavaScript ์ฝ๋๋ฒ ์ด์ค์ ๋ช ํ์ฑ๊ณผ ํ๋ ฅ์ฑ์ ๋ถ์ฌํ๋ ์ ์ ํ์ดํ์ ์ ๊ณตํฉ๋๋ค. ๋ณต์กํ ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ํด ํ์ ํ๋ ๊ตญ์ ํ์๊ฒ๋ ๋ค์ํ ๋ชจ๋๊ณผ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๊ฑธ์ณ ํ์ ์ ์ ์ํ๊ณ ๊ฐ์ ํ ์ ์๋ ๋ฅ๋ ฅ์ด ๋งค์ฐ ์ค์ํฉ๋๋ค.
๊ทธ๋ฌ๋ TypeScript ํ๋ก์ ํธ๋ ๊ฑฐ์ ๋
๋ฆฝ์ ์ผ๋ก ์กด์ฌํ์ง ์์ต๋๋ค. ๊ธฐ์กด JavaScript ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ์์ฃผ ์ํธ ์์ฉํ๊ณ , ๋ธ๋ผ์ฐ์ ๊ธฐ๋ณธ API์ ํตํฉํ๊ฑฐ๋, ์ ์ญ์ ์ผ๋ก ์ฌ์ฉ ๊ฐ๋ฅํ ๊ฐ์ฒด๋ฅผ ํ์ฅํฉ๋๋ค. ์ด ์ง์ ์์ TypeScript์ ์ ์ธ ํ์ผ(.d.ts)์ด ํ์์ ์ธ๋ฐ, ๋ฐํ์ ๋์์ ๋ณ๊ฒฝํ์ง ์๊ณ TypeScript ์ปดํ์ผ๋ฌ์ JavaScript ์ฝ๋์ ํํ๋ฅผ ์ค๋ช
ํ ์ ์๊ฒ ํด์ค๋๋ค. ์ด ๊ฐ๋ ฅํ ๋ฉ์ปค๋์ฆ ๋ด์์ ์ธ๋ถ ํ์
์ ์ฒ๋ฆฌํ๋ ๋ ๊ฐ์ง ์ฃผ์ ์ ๊ทผ ๋ฐฉ์์ด ๋๋๋ฌ์ง๋๋ค: ์ฐ๋น์ธํธ ๋ชจ๋ ์ ์ธ(Ambient Module Declarations)๊ณผ ์ ์ญ ํ์
์ ์(Global Type Definitions).
์ฐ๋น์ธํธ ๋ชจ๋๊ณผ ์ ์ญ ํ์ ์ ์๋ฅผ ์ธ์ ์ด๋ป๊ฒ ํจ๊ณผ์ ์ผ๋ก ์ฌ์ฉํ ์ง ์ดํดํ๋ ๊ฒ์ ๋ชจ๋ TypeScript ๊ฐ๋ฐ์, ํนํ ๊ธ๋ก๋ฒ ์ฌ์ฉ์๋ฅผ ๋์์ผ๋ก ํ๋ ๋๊ท๋ชจ ์ํฐํ๋ผ์ด์ฆ๊ธ ์๋ฃจ์ ์ ๊ตฌ์ถํ๋ ๊ฐ๋ฐ์์๊ฒ๋ ํ์์ ์ ๋๋ค. ์๋ชป ์ ์ฉํ๋ฉด ํ์ ์ถฉ๋, ๋ถ๋ถ๋ช ํ ์์กด์ฑ, ๊ทธ๋ฆฌ๊ณ ์ ์ง๋ณด์์ฑ ์ ํ๋ก ์ด์ด์ง ์ ์์ต๋๋ค. ์ด ํฌ๊ด์ ์ธ ๊ฐ์ด๋๋ ์ด๋ฌํ ๊ฐ๋ ์ ์ฌ์ธต์ ์ผ๋ก ํ๊ตฌํ๋ฉฐ, ํ์ ๊ท๋ชจ๋ ์ง๋ฆฌ์ ๋ถํฌ์ ๊ด๊ณ์์ด TypeScript ํ๋ก์ ํธ์์ ์ ๋ณด์ ์ ๊ฐํ ๊ฒฐ์ ์ ๋ด๋ฆฌ๋ ๋ฐ ๋์์ด ๋๋ ์ค์ฉ์ ์ธ ์์ ์ ๋ชจ๋ฒ ์ฌ๋ก๋ฅผ ์ ๊ณตํฉ๋๋ค.
TypeScript ํ์ ์์คํ ๊ณผ ๊ธ๋ก๋ฒ ์ํํธ์จ์ด ๊ฐ๋ฐ์์์ ์ญํ
TypeScript๋ ์ ์ ํ์ ์ ์ถ๊ฐํ์ฌ JavaScript๋ฅผ ํ์ฅํจ์ผ๋ก์จ ๊ฐ๋ฐ์๊ฐ ๋ฐํ์์ด ์๋ ๊ฐ๋ฐ ์ฃผ๊ธฐ ์ด๊ธฐ์ ์ค๋ฅ๋ฅผ ์ก์๋ผ ์ ์๋๋ก ํฉ๋๋ค. ์ ์ธ๊ณ์ ์ผ๋ก ๋ถ์ฐ๋ ํ์๊ฒ ์ด๋ ๋ค์๊ณผ ๊ฐ์ ์ฌ๋ฌ ๊ฐ์ง ์ฌ์คํ ์ด์ ์ ์ ๊ณตํฉ๋๋ค:
- ํฅ์๋ ํ์ : ๋ช ์์ ์ธ ํ์ ์ ํตํด ์๋ก ๋ค๋ฅธ ์๊ฐ๋์ ๋ฌธํ์ ๋ฐฐ๊ฒฝ์ ๊ฐ์ง ํ ๊ตฌ์ฑ์๋ค์ ํจ์, ์ธํฐํ์ด์ค, ํด๋์ค์ ์์ ์ ๋ ฅ๊ณผ ์ถ๋ ฅ์ ๋ ์ฝ๊ฒ ์ดํดํ์ฌ ์คํด์ ์ปค๋ฎค๋์ผ์ด์ ์ค๋ฒํค๋๋ฅผ ์ค์ผ ์ ์์ต๋๋ค.
- ๊ฐ์ ๋ ์ ์ง๋ณด์์ฑ: ํ๋ก์ ํธ๊ฐ ์งํํ๊ณ ๋ค์ํ ํ์ ์ํด ์๋ก์ด ๊ธฐ๋ฅ์ด ์ถ๊ฐ๋จ์ ๋ฐ๋ผ ํ์ ์ ์ธ์ ๊ณ์ฝ ์ญํ ์ ํ์ฌ ์์คํ ์ ํ ๋ถ๋ถ์์ ๋ณ๊ฒฝ ์ฌํญ์ด ์๋์น ์๊ฒ ๋ค๋ฅธ ๋ถ๋ถ์ ์์์ํค์ง ์๋๋ก ๋ณด์ฅํฉ๋๋ค. ์ด๋ ์ฅ๊ธฐ์ ์ธ ์ ํ๋ฆฌ์ผ์ด์ ์ ๋งค์ฐ ์ค์ํฉ๋๋ค.
- ๋ฆฌํฉํ ๋ง ์์ ๊ฐ: ์๊ฐ์ด ์ง๋จ์ ๋ฐ๋ผ ๋ง์ ๊ธฐ์ฌ์์ ์ํด ๊ตฌ์ถ๋ ๋๊ท๋ชจ ์ฝ๋๋ฒ ์ด์ค๋ TypeScript์ ๋ฆฌํฉํ ๋ง ๊ธฐ๋ฅ์ผ๋ก๋ถํฐ ์์ฒญ๋ ์ด์ ์ ์ป์ต๋๋ค. ์ปดํ์ผ๋ฌ๋ ๊ฐ๋ฐ์๊ฐ ํ์ํ ํ์ ์ ๋ฐ์ดํธ๋ฅผ ์๋ดํ์ฌ ์ค์ํ ๊ตฌ์กฐ์ ๋ณ๊ฒฝ์ ๋ ์ด๋ ต๊ฒ ๋ง๋ญ๋๋ค.
- ๋๊ตฌ ์ง์: ์๋ ์์ฑ, ์๊ทธ๋์ฒ ๋์๋ง, ์ง๋ฅํ ์ค๋ฅ ๋ณด๊ณ ์ ๊ฐ์ ๊ณ ๊ธ IDE ๊ธฐ๋ฅ์ TypeScript์ ํ์ ์ ๋ณด์ ์ํด ๊ตฌ๋๋์ด ์ ์ธ๊ณ ๊ฐ๋ฐ์์ ์์ฐ์ฑ์ ๋์ ๋๋ค.
๊ธฐ์กด JavaScript์ TypeScript๋ฅผ ํ์ฉํ๋ ํต์ฌ์ ํ์
์ ์ธ ํ์ผ(.d.ts)์ ์์ต๋๋ค. ์ด ํ์ผ๋ค์ ๋ธ๋ฆฌ์ง ์ญํ ์ ํ์ฌ, TypeScript ์ปดํ์ผ๋ฌ๊ฐ ์ค์ค๋ก ์ถ๋ก ํ ์ ์๋ JavaScript ์ฝ๋์ ๋ํ ํ์
์ ๋ณด๋ฅผ ์ ๊ณตํฉ๋๋ค. ์ด๋ฅผ ํตํด ์ํํ ์ํธ ์ด์ฉ์ฑ์ด ๊ฐ๋ฅํด์ง๋ฉฐ, TypeScript๊ฐ JavaScript ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ํ๋ ์์ํฌ๋ฅผ ์์ ํ๊ฒ ์ฌ์ฉํ ์ ์๊ฒ ํฉ๋๋ค.
ํ์
์ ์ธ ํ์ผ(.d.ts) ์ดํดํ๊ธฐ
.d.ts ํ์ผ์ ์ค์ ๊ตฌํ ์ฝ๋ ์์ด ํ์
์ ์๋ง ํฌํจํฉ๋๋ค. ์ด๋ C++์ ํค๋ ํ์ผ์ด๋ Java์ ์ธํฐํ์ด์ค ํ์ผ๊ณผ ์ ์ฌํ๋ฉฐ, ๋ชจ๋ ๋๋ ์ ์ญ ์ํฐํฐ์ ๊ณต๊ฐ API๋ฅผ ์ค๋ช
ํฉ๋๋ค. TypeScript ์ปดํ์ผ๋ฌ๊ฐ ํ๋ก์ ํธ๋ฅผ ์ฒ๋ฆฌํ ๋, ์ด ์ ์ธ ํ์ผ๋ค์ ์ฐพ์ ์ธ๋ถ JavaScript ์ฝ๋๊ฐ ์ ๊ณตํ๋ ํ์
์ ์ดํดํฉ๋๋ค. ์ด๋ฅผ ํตํด TypeScript ์ฝ๋๋ JavaScript ํจ์๋ฅผ ํธ์ถํ๊ณ , JavaScript ํด๋์ค๋ฅผ ์ธ์คํด์คํํ๋ฉฐ, ์์ ํ ํ์
์์ ์ฑ์ผ๋ก JavaScript ๊ฐ์ฒด์ ์ํธ ์์ฉํ ์ ์์ต๋๋ค.
๋๋ถ๋ถ์ ์ธ๊ธฐ ์๋ JavaScript ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๊ฒฝ์ฐ, ํ์
์ ์ธ์ ์ด๋ฏธ npm์ @types ์กฐ์ง( DefinitelyTyped ํ๋ก์ ํธ์ ์ํด ๊ตฌ๋๋จ)์ ํตํด ์ฌ์ฉํ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด, npm install @types/react๋ฅผ ์ค์นํ๋ฉด React ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๋ํ ํ์
์ ์๊ฐ ์ ๊ณต๋ฉ๋๋ค. ๊ทธ๋ฌ๋ ๋ค์๊ณผ ๊ฐ์ ์๋๋ฆฌ์ค์์๋ ์์ฒด ์ ์ธ ํ์ผ์ ์์ฑํด์ผ ํฉ๋๋ค:
- ํ์ ์ ์๊ฐ ์๋ ์ฌ์ฉ์ ์ง์ ๋ด๋ถ JavaScript ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ฌ์ฉ.
- ์ค๋๋๊ฑฐ๋ ์ ์ง๋ณด์๊ฐ ๋ ๋๋ ์๋ํํฐ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์์ .
- ๋น JavaScript ์์ฐ(์: ์ด๋ฏธ์ง, CSS ๋ชจ๋)์ ๋ํ ํ์ ์ ์ธ.
- ์ ์ญ ๊ฐ์ฒด ๋๋ ๊ธฐ๋ณธ ํ์ ํ์ฅ.
์ด๋ฌํ ์ฌ์ฉ์ ์ง์ ์ ์ธ ์๋๋ฆฌ์ค์์ ์ฐ๋น์ธํธ ๋ชจ๋ ์ ์ธ๊ณผ ์ ์ญ ํ์ ์ ์ ๊ฐ์ ๊ตฌ๋ถ์ด ์ค์ํด์ง๋๋ค.
์ฐ๋น์ธํธ ๋ชจ๋ ์ ์ธ(declare module 'module-name')
์ฐ๋น์ธํธ ๋ชจ๋ ์ ์ธ์ ์์ฒด ํ์
์ ์๊ฐ ์๋ ์ธ๋ถ JavaScript ๋ชจ๋์ ํํ๋ฅผ ์ค๋ช
ํ๋ ๋ฐ ์ฌ์ฉ๋ฉ๋๋ค. ๋ณธ์ง์ ์ผ๋ก TypeScript ์ปดํ์ผ๋ฌ์๊ฒ "โXโ๋ผ๋ ๋ชจ๋์ด ์๋๋ฐ, ํด๋น ๋ชจ๋์ export๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค."๋ผ๊ณ ์๋ ค์ฃผ๋ ๊ฒ์
๋๋ค. ์ด๋ฅผ ํตํด ํด๋น ๋ชจ๋์ TypeScript ์ฝ๋์ importํ๊ฑฐ๋ requireํ์ฌ ์์ ํ ํ์
๊ฒ์ฌ๋ฅผ ํ ์ ์์ต๋๋ค.
์ฐ๋น์ธํธ ๋ชจ๋ ์ ์ธ์ ์ฌ์ฉํด์ผ ํ๋ ๊ฒฝ์ฐ
๋ค์๊ณผ ๊ฐ์ ์ํฉ์์๋ ์ฐ๋น์ธํธ ๋ชจ๋ ์ ์ธ์ ์ ํํด์ผ ํฉ๋๋ค:
@types๊ฐ ์๋ ์๋ํํฐ JavaScript ๋ผ์ด๋ธ๋ฌ๋ฆฌ: ๊ณต์@typesํจํค์ง๊ฐ ์๋ JavaScript ๋ผ์ด๋ธ๋ฌ๋ฆฌ(์: ์ค๋๋ ์ ํธ๋ฆฌํฐ, ์ ๋ฌธ ์ฐจํธ ๋๊ตฌ ๋๋ ๋ ์ ์ ์ธ ๋ด๋ถ ๋ผ์ด๋ธ๋ฌ๋ฆฌ)๋ฅผ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ, ํด๋น ๋ชจ๋์ ์ง์ ์ ์ธํด์ผ ํฉ๋๋ค.- ์ฌ์ฉ์ ์ง์ JavaScript ๋ชจ๋: ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ ๊ฑฐ์ ๋ถ๋ถ์ด ์์ JavaScript๋ก ์์ฑ๋์๊ณ , ์ด๋ฅผ TypeScript์์ ์ฌ์ฉํ๊ณ ์ ํ๋ ๊ฒฝ์ฐ ํด๋น ๋ชจ๋์ ์ ์ธํ ์ ์์ต๋๋ค.
- ๋น์ฝ๋ ์์ฐ ์ํฌํธ: JavaScript ์ฝ๋๋ฅผ exportํ์ง ์์ง๋ง ๋ฒ๋ค๋ฌ(Webpack ๋๋ Rollup๊ณผ ๊ฐ์)์ ์ํด ์ฒ๋ฆฌ๋๋ ๋ชจ๋(์: ์ด๋ฏธ์ง(
.svg,.png), CSS ๋ชจ๋(.css,.scss), ๋๋ JSON ํ์ผ)์ ๊ฒฝ์ฐ, ํ์ ์์ ํ ์ํฌํธ๋ฅผ ํ์ฑํํ๊ธฐ ์ํด ํด๋น ๋ชจ๋์ ์ ์ธํ ์ ์์ต๋๋ค.
๊ตฌ๋ฌธ ๋ฐ ๊ตฌ์กฐ
์ฐ๋น์ธํธ ๋ชจ๋ ์ ์ธ์ ์ผ๋ฐ์ ์ผ๋ก .d.ts ํ์ผ์ ์์ผ๋ฉฐ ๋ค์ ๊ธฐ๋ณธ ๊ตฌ์กฐ๋ฅผ ๋ฐ๋ฆ
๋๋ค:
declare module 'module-name' {
// Declare exports here
export function myFunction(arg: string): number;
export const myConstant: string;
export interface MyInterface { prop: boolean; }
export class MyClass { constructor(name: string); greeting: string; }
// If the module exports a default, use 'export default'
export default function defaultExport(value: any): void;
}
module-name์ import ๋ฌธ์์ ์ฌ์ฉํ ๋ฌธ์์ด๊ณผ ์ ํํ ์ผ์นํด์ผ ํฉ๋๋ค(์: 'lodash-es-legacy' ๋๋ './utils/my-js-utility').
์ค์ฉ์ ์ธ ์์ 1: @types๊ฐ ์๋ ์๋ํํฐ ๋ผ์ด๋ธ๋ฌ๋ฆฌ
ํ์
์ ์๊ฐ ์๋ 'd3-legacy-charts'๋ผ๋ ๋ ๊ฑฐ์ JavaScript ์ฐจํธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ๋ค๊ณ ๊ฐ์ ํด ๋ด
์๋ค. JavaScript ํ์ผ node_modules/d3-legacy-charts/index.js๋ ๋ค์๊ณผ ๊ฐ์ด ์๊ฒผ์ ์ ์์ต๋๋ค:
// d3-legacy-charts/index.js (simplified)
export function createBarChart(data, elementId) {
console.log('Creating bar chart with data:', data, 'on', elementId);
// ... actual D3 chart creation logic ...
return { success: true, id: elementId };
}
export function createLineChart(data, elementId) {
console.log('Creating line chart with data:', data, 'on', elementId);
// ... actual D3 chart creation logic ...
return { success: true, id: elementId };
}
์ด๋ฅผ TypeScript ํ๋ก์ ํธ์์ ์ฌ์ฉํ๋ ค๋ฉด, ์๋ฅผ ๋ค์ด src/types/d3-legacy-charts.d.ts์ ๊ฐ์ ์ ์ธ ํ์ผ์ ์์ฑํด์ผ ํฉ๋๋ค:
declare module 'd3-legacy-charts' {
interface ChartResult {
success: boolean;
id: string;
}
export function createBarChart(data: number[], elementId: string): ChartResult;
export function createLineChart(data: { x: number; y: number }[], elementId: string): ChartResult;
}
์ด์ TypeScript ์ฝ๋์์ ํ์ ์์ ์ฑ์ ํ๋ณดํ์ฌ ๊ฐ์ ธ์ ์ฌ์ฉํ ์ ์์ต๋๋ค:
import { createBarChart, createLineChart } from 'd3-legacy-charts';
const chartData = [10, 20, 30, 40, 50];
const lineChartData = [{ x: 1, y: 10 }, { x: 2, y: 20 }];
const barChartStatus = createBarChart(chartData, 'myBarChartContainer');
console.log(barChartStatus.success); // Type-checked access
// TypeScript will now correctly flag if you pass wrong arguments:
// createLineChart(chartData, 'anotherContainer'); // Error: Argument of type 'number[]' is not assignable to parameter of type '{ x: number; y: number; }[]'.
tsconfig.json์ ์ฌ์ฉ์ ์ง์ ํ์
๋๋ ํฐ๋ฆฌ๊ฐ ํฌํจ๋์ด ์๋์ง ํ์ธํ์ญ์์ค:
{
"compilerOptions": {
// ... other options
"typeRoots": ["./node_modules/@types", "./src/types"]
},
"include": ["src/**/*.ts", "src/**/*.d.ts"]
}
์ค์ฉ์ ์ธ ์์ 2: ๋น์ฝ๋ ์์ฐ ์ ์ธ
Webpack๊ณผ ๊ฐ์ ๋ฒ๋ค๋ฌ๋ฅผ ์ฌ์ฉํ ๋, ์ฝ๋์ ๋น JavaScript ์์ฐ์ ์ง์ ๊ฐ์ ธ์ค๋ ๊ฒฝ์ฐ๊ฐ ๋ง์ต๋๋ค. ์๋ฅผ ๋ค์ด, SVG ํ์ผ์ ๊ฐ์ ธ์ค๋ฉด ํด๋น ๊ฒฝ๋ก ๋๋ React ์ปดํฌ๋ํธ๋ฅผ ๋ฐํํ ์ ์์ต๋๋ค. ์ด๋ฅผ ํ์ ์์ ํ๊ฒ ๋ง๋ค๋ ค๋ฉด ์ด๋ฌํ ํ์ผ ํ์์ ๋ํ ๋ชจ๋์ ์ ์ธํ ์ ์์ต๋๋ค.
์๋ฅผ ๋ค์ด, src/types/assets.d.ts ํ์ผ์ ์์ฑํฉ๋๋ค:
declare module '*.svg' {
import React = require('react');
export const ReactComponent: React.FC<React.SVGProps<SVGSVGElement> & React.HTMLAttributes<SVGSVGElement>>;
const src: string;
export default src;
}
declare module '*.png' {
const value: string;
export default value;
}
declare module '*.jpg' {
const value: string;
export default value;
}
declare module '*.jpeg' {
const value: string;
export default value;
}
declare module '*.gif' {
const value: string;
export default value;
}
declare module '*.bmp' {
const value: string;
export default value;
}
declare module '*.tiff' {
const value: string;
export default value;
}
declare module '*.webp' {
const value: string;
export default value;
}
declare module '*.ico' {
const value: string;
export default value;
}
declare module '*.avif' {
const value: string;
export default value;
}
์ด์ ํ์ ์์ ์ฑ์ ํ๋ณดํ์ฌ ์ด๋ฏธ์ง ํ์ผ์ ๊ฐ์ ธ์ฌ ์ ์์ต๋๋ค:
import myImage from './assets/my-image.png';
import { ReactComponent as MyIcon } from './assets/my-icon.svg';
function MyComponent() {
return (
<div>
<img src={myImage} alt="My Image" />
<MyIcon style={{ width: 24, height: 24 }} />
</div>
);
}
์ฐ๋น์ธํธ ๋ชจ๋ ์ ์ธ์ ์ฃผ์ ๊ณ ๋ ค ์ฌํญ
- ์ธ๋ถ์ฑ: ๋ชจ๋ ์ฐ๋น์ธํธ ๋ชจ๋ ์ ์ธ์ ๋ํด ๋จ์ผ
.d.tsํ์ผ์ ์์ฑํ๊ฑฐ๋ ๋ ผ๋ฆฌ์ ์ผ๋ก ๋ถ๋ฆฌํ ์ ์์ต๋๋ค(์:legacy-libs.d.ts,asset-declarations.d.ts). ๊ธ๋ก๋ฒ ํ์ ๊ฒฝ์ฐ ๊ฒ์ ๊ฐ๋ฅ์ฑ์ ์ํด ๋ช ํํ ๋ถ๋ฆฌ์ ๋ช ๋ช ๊ท์น์ด ์ค์ํฉ๋๋ค. - ๋ฐฐ์น: ๊ด๋ก์ ์ผ๋ก ์ฌ์ฉ์ ์ง์
.d.tsํ์ผ์ ํ๋ก์ ํธ ๋ฃจํธ์src/types/๋๋types/๋๋ ํฐ๋ฆฌ์ ๋ฐฐ์น๋ฉ๋๋ค. ์์์ ์ผ๋ก ๊ฐ์ ธ์ค์ง ์๋ ๊ฒฝ์ฐtsconfig.json์ ์ด๋ฌํ ๊ฒฝ๋ก๊ฐtypeRoots์ ํฌํจ๋์ด ์๋์ง ํ์ธํ์ญ์์ค. - ์ ์ง๋ณด์: ์๋์ผ๋ก ํ์
์ ์ง์ ํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๋ํด ๊ณต์
@typesํจํค์ง๊ฐ ์ ๊ณต๋๋ ๊ฒฝ์ฐ, ์ถฉ๋์ ํผํ๊ณ ๊ณต์์ ์ด๊ณ ์ข ์ข ๋ ์์ ํ ํ์ ์ ์์ ์ด์ ์ ์ป๊ธฐ ์ํด ์ฌ์ฉ์ ์ง์ ์ฐ๋น์ธํธ ๋ชจ๋ ์ ์ธ์ ์ ๊ฑฐํด์ผ ํฉ๋๋ค. - ๋ชจ๋ ํด๊ฒฐ: TypeScript๊ฐ ๋ฐํ์์ ์ค์ JavaScript ๋ชจ๋์ ์ฐพ์ ์ ์๋๋ก
tsconfig.json์ ์ ์ ํmoduleResolution์ค์ (์:"node")์ด ์๋์ง ํ์ธํ์ญ์์ค.
์ ์ญ ํ์
์ ์(declare global)
ํน์ ๋ชจ๋์ ์ค๋ช
ํ๋ ์ฐ๋น์ธํธ ๋ชจ๋๊ณผ ๋ฌ๋ฆฌ, ์ ์ญ ํ์
์ ์๋ ์ ์ญ ์ค์ฝํ๋ฅผ ํ์ฅํ๊ฑฐ๋ ์ฆ๊ฐํฉ๋๋ค. ์ด๋ declare global ๋ธ๋ก ๋ด์์ ์ ์ธ๋ ๋ชจ๋ ํ์
, ์ธํฐํ์ด์ค ๋๋ ๋ณ์๊ฐ ๋ช
์์ ์ธ import ๋ฌธ ์์ด TypeScript ํ๋ก์ ํธ์ ๋ชจ๋ ๊ณณ์์ ์ฌ์ฉํ ์ ์์์ ์๋ฏธํฉ๋๋ค. ์ด๋ฌํ ์ ์ธ์ ์ผ๋ฐ์ ์ผ๋ก ํ์ผ์ด ์ ์ญ ์คํฌ๋ฆฝํธ ํ์ผ๋ก ์ฒ๋ฆฌ๋๋ ๊ฒ์ ๋ฐฉ์งํ๊ธฐ ์ํด ๋ชจ๋(์: ๋น ๋ชจ๋ ๋๋ export๊ฐ ์๋ ๋ชจ๋) ๋ด์ ๋ฐฐ์น๋ฉ๋๋ค. ํ์ผ์ด ์ ์ญ ์คํฌ๋ฆฝํธ ํ์ผ๋ก ์ฒ๋ฆฌ๋๋ฉด ๋ชจ๋ ์ ์ธ์ด ๊ธฐ๋ณธ์ ์ผ๋ก ์ ์ญ์ด ๋ฉ๋๋ค.
์ ์ญ ํ์ ์ ์๋ฅผ ์ฌ์ฉํด์ผ ํ๋ ๊ฒฝ์ฐ
์ ์ญ ํ์ ์ ์๋ ๋ค์๊ณผ ๊ฐ์ ๊ฒฝ์ฐ์ ์ ํฉํฉ๋๋ค:
- ๋ธ๋ผ์ฐ์ ์ ์ญ ๊ฐ์ฒด ํ์ฅ:
window,document๋๋HTMLElement์ ๊ฐ์ ํ์ค ๋ธ๋ผ์ฐ์ ๊ฐ์ฒด์ ์ฌ์ฉ์ ์ง์ ์์ฑ ๋๋ ๋ฉ์๋๋ฅผ ์ถ๊ฐํ๋ ๊ฒฝ์ฐ. - ์ ์ญ ๋ณ์/๊ฐ์ฒด ์ ์ธ: ์ ํ๋ฆฌ์ผ์ด์ ๋ฐํ์ ์ ๋ฐ์ ๊ฑธ์ณ ์ค์ ๋ก ์ ์ญ์ ์ผ๋ก ์ก์ธ์คํ ์ ์๋ ๋ณ์ ๋๋ ๊ฐ์ฒด(์: ์ ์ญ ๊ตฌ์ฑ ๊ฐ์ฒด ๋๋ ๊ธฐ๋ณธ ํ์ ์ ํ๋กํ ํ์ ์ ์์ ํ๋ ํด๋ฆฌํ)์ ๊ฒฝ์ฐ.
- ํด๋ฆฌํ ๋ฐ ์ฌ(Shim) ๋ผ์ด๋ธ๋ฌ๋ฆฌ: ๊ธฐ๋ณธ ํ์
์ ๋ฉ์๋๋ฅผ ์ถ๊ฐํ๋ ํด๋ฆฌํ(์:
Array.prototype.myCustomMethod)์ ๋์ ํ ๋. - Node.js ์ ์ญ ๊ฐ์ฒด ์ฆ๊ฐ: ๋ธ๋ผ์ฐ์
window์ ์ ์ฌํ๊ฒ ์๋ฒ์ธก ์ ํ๋ฆฌ์ผ์ด์ ์ Node.jsglobal๋๋process.env๋ฅผ ํ์ฅํ๋ ๊ฒฝ์ฐ.
๊ตฌ๋ฌธ ๋ฐ ๊ตฌ์กฐ
์ ์ญ ์ค์ฝํ๋ฅผ ์ฆ๊ฐํ๋ ค๋ฉด declare global ๋ธ๋ก์ ๋ชจ๋ ๋ด์ ๋ฐฐ์นํด์ผ ํฉ๋๋ค. ์ฆ, .d.ts ํ์ผ์๋ ๋ชจ๋๋ก ๋ง๋ค๊ธฐ ์ํด ํ๋ ์ด์์ import ๋๋ export ๋ฌธ(์ฌ์ง์ด ๋น ๋ฌธ์ด๋ผ๋)์ด ํฌํจ๋์ด์ผ ํฉ๋๋ค. import/export๊ฐ ์๋ ๋
๋ฆฝํ .d.ts ํ์ผ์ธ ๊ฒฝ์ฐ, ๋ชจ๋ ์ ์ธ์ด ๊ธฐ๋ณธ์ ์ผ๋ก ์ ์ญ์ด ๋๋ฉฐ declare global์ ์๊ฒฉํ๊ฒ ํ์ํ์ง ์์ง๋ง, ์ด๋ฅผ ๋ช
์์ ์ผ๋ก ์ฌ์ฉํ๋ฉด ์๋๋ฅผ ๋ช
ํํ๊ฒ ์ ๋ฌํ ์ ์์ต๋๋ค.
// Example of a module that augments the global scope
// global.d.ts or augmentations.d.ts
export {}; // Makes this file a module, so declare global can be used
declare global {
interface Window {
myGlobalConfig: { apiUrl: string; version: string; };
myAnalyticsTracker: (eventName: string, data?: object) => void;
}
// Declare a global function
function calculateChecksum(data: string): string;
// Declare a global variable
var MY_APP_NAME: string;
// Extend a native interface (e.g., for polyfills)
interface Array<T> {
first(): T | undefined;
last(): T | undefined;
}
}
์ค์ฉ์ ์ธ ์์ 1: Window ๊ฐ์ฒด ํ์ฅ
์ ์ญ ์ ํ๋ฆฌ์ผ์ด์
์ค์ (์๋ง๋ ๋ ๊ฑฐ์ JavaScript ๋ฒ๋ค ๋๋ ํ์ด์ง์ ์ฃผ์
๋ ์ธ๋ถ ์คํฌ๋ฆฝํธ)์ด ๋ธ๋ผ์ฐ์ ์ window ๊ฐ์ฒด์ myAppConfig ๊ฐ์ฒด์ analytics ํจ์๋ฅผ ์ง์ ์ฌ์ฉํ ์ ์๋๋ก ํ๋ค๊ณ ๊ฐ์ ํด ๋ด
์๋ค. TypeScript์์ ์ด๋ฌํ ๊ฐ์ฒด์ ์์ ํ๊ฒ ์ก์ธ์คํ๋ ค๋ฉด, ์๋ฅผ ๋ค์ด src/types/window.d.ts์ ๊ฐ์ ์ ์ธ ํ์ผ์ ์์ฑํด์ผ ํฉ๋๋ค:
// src/types/window.d.ts
export {}; // This makes the file a module, allowing 'declare global'
declare global {
interface Window {
myAppConfig: {
apiBaseUrl: string;
environment: 'development' | 'production';
featureFlags: Record<string, boolean>;
};
analytics: {
trackEvent(eventName: string, properties?: Record<string, any>): void;
identifyUser(userId: string, traits?: Record<string, any>): void;
};
}
}
์ด์ ๋ชจ๋ TypeScript ํ์ผ์์ ์์ ํ ํ์ ๊ฒ์ฌ๋ฅผ ํตํด ์ด๋ฌํ ์ ์ญ ์์ฑ์ ์ก์ธ์คํ ์ ์์ต๋๋ค:
// In any .ts file
console.log(window.myAppConfig.apiBaseUrl);
window.analytics.trackEvent('page_view', { path: '/dashboard' });
// TypeScript will catch errors:
// window.analytics.trackEvent(123); // Error: Argument of type 'number' is not assignable to parameter of type 'string'.
// console.log(window.myAppConfig.nonExistentProperty); // Error: Property 'nonExistentProperty' does not exist on type '{ apiBaseUrl: string; ... }'.
์ค์ฉ์ ์ธ ์์ 2: ๊ธฐ๋ณธ ํ์ ์ฆ๊ฐ(ํด๋ฆฌํ)
๊ธฐ๋ณธ JavaScript ํ๋กํ ํ์
(์: Array.prototype)์ ์ ๋ฉ์๋๋ฅผ ์ถ๊ฐํ๋ ํด๋ฆฌํ ๋๋ ์ฌ์ฉ์ ์ง์ ์ ํธ๋ฆฌํฐ๋ฅผ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ, ์ด๋ฌํ ์ฆ๊ฐ์ ์ ์ญ์ ์ผ๋ก ์ ์ธํด์ผ ํฉ๋๋ค. String.prototype์ .isEmpty() ๋ฉ์๋๋ฅผ ์ถ๊ฐํ๋ ์ ํธ๋ฆฌํฐ๊ฐ ์๋ค๊ณ ๊ฐ์ ํด ๋ด
์๋ค.
src/types/polyfills.d.ts์ ๊ฐ์ ํ์ผ์ ์์ฑํฉ๋๋ค:
// src/types/polyfills.d.ts
export {}; // Ensures this is treated as a module
declare global {
interface String {
isEmpty(): boolean;
isPalindrome(): boolean;
}
interface Array<T> {
/**
* Returns the first element of the array, or undefined if the array is empty.
*/
first(): T | undefined;
/**
* Returns the last element of the array, or undefined if the array is empty.
*/
last(): T | undefined;
}
}
๊ทธ๋ฐ ๋ค์ ์ค์ JavaScript ํด๋ฆฌํ์ ๋ง๋ญ๋๋ค:
// src/utils/string-polyfills.js
if (!String.prototype.isEmpty) {
String.prototype.isEmpty = function() {
return this.length === 0;
};
}
if (!String.prototype.isPalindrome) {
String.prototype.isPalindrome = function() {
const cleaned = this.toLowerCase().replace(/[^a-z0-9]/g, '');
return cleaned === cleaned.split('').reverse().join('');
};
}
์ด๋ฌํ ๋ฉ์๋๋ฅผ ์ฌ์ฉํ๋ TypeScript ์ฝ๋๋ณด๋ค JavaScript ํด๋ฆฌํ์ด ๋จผ์ ๋ก๋๋๋๋ก ํด์ผ ํฉ๋๋ค. ์ ์ธ์ ํตํด TypeScript ์ฝ๋๋ ํ์ ์์ ์ฑ์ ์ป์ต๋๋ค:
// In any .ts file
const myString = "Hello World";
console.log(myString.isEmpty()); // false
console.log("".isEmpty()); // true
console.log("madam".isPalindrome()); // true
const numbers = [1, 2, 3];
console.log(numbers.first()); // 1
console.log(numbers.last()); // 3
const emptyArray: number[] = [];
console.log(emptyArray.first()); // undefined
// TypeScript will flag if you try to use a non-existent method:
// console.log(myString.toUpper()); // Error: Property 'toUpper' does not exist on type 'String'.
์ ์ญ ํ์ ์ ์์ ์ฃผ์ ๊ณ ๋ ค ์ฌํญ
- ๊ทน๋์ ์ฃผ์์ ํจ๊ป ์ฌ์ฉ: ๊ฐ๋ ฅํ์ง๋ง, ์ ์ญ ์ค์ฝํ ํ์ฅ์ ๋๋ฌผ๊ฒ ์ํ๋์ด์ผ ํฉ๋๋ค. ์ด๋ ํ์ ์ด๋ ๋ณ์๊ฐ ๋ค๋ฅธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ๋๋ ๋ฏธ๋์ JavaScript ๊ธฐ๋ฅ๊ณผ ์๋์น ์๊ฒ ์ถฉ๋ํ๋ "์ ์ญ ์ค์ผ"์ผ๋ก ์ด์ด์ง ์ ์์ต๋๋ค. ์ด๋ ๋ค๋ฅธ ํ์ด ์ถฉ๋ํ๋ ์ ์ญ ์ ์ธ์ ๋์ ํ ์ ์๋ ๋๊ท๋ชจ ์ ์ญ ๋ถ์ฐ ์ฝ๋๋ฒ ์ด์ค์์ ํนํ ๋ฌธ์ ๊ฐ ๋ฉ๋๋ค.
- ํน์ ์ฑ: ์ ์ญ ํ์ ์ ์ ์ํ ๋ ๊ฐ๋ฅํ ํ ๊ตฌ์ฒด์ ์ผ๋ก ๋ง๋์ญ์์ค. ์ฝ๊ฒ ์ถฉ๋ํ ์ ์๋ ์ผ๋ฐ์ ์ธ ์ด๋ฆ์ ํผํ์ญ์์ค.
- ์ํฅ: ์ ์ญ ์ ์ธ์ ์ ์ฒด ์ฝ๋๋ฒ ์ด์ค์ ์ํฅ์ ๋ฏธ์นฉ๋๋ค. ๋ชจ๋ ์ ์ญ ํ์ ์ ์๊ฐ ๋ณดํธ์ ์ผ๋ก ์ฌ์ฉ ๊ฐ๋ฅํ๋๋ก ์๋๋์๋์ง, ๊ทธ๋ฆฌ๊ณ ์ํคํ ์ฒ ํ์ ์ํด ์ฒ ์ ํ ๊ฒํ ๋์๋์ง ํ์ธํ์ญ์์ค.
- ๋ชจ๋์ฑ vs. ์ ์ญ: ์ต์ JavaScript ๋ฐ TypeScript๋ ๋ชจ๋์ฑ์ ๊ฐ๋ ฅํ ์ ํธํฉ๋๋ค. ์ ์ญ ํ์ ์ ์๋ฅผ ์ฌ์ฉํ๊ธฐ ์ ์ ๋ช ์์ ์ผ๋ก ๊ฐ์ ธ์จ ๋ชจ๋ ๋๋ ์์กด์ฑ์ผ๋ก ์ ๋ฌ๋ ์ ํธ๋ฆฌํฐ ํจ์๊ฐ ๋ ๊น๋ํ๊ณ ๋ ์นจ์ ์ ์ธ ์๋ฃจ์ ์ธ์ง ๊ณ ๋ คํ์ญ์์ค.
๋ชจ๋ ์ฆ๊ฐ(declare module 'module-name' { ... })
๋ชจ๋ ์ฆ๊ฐ์ ๊ธฐ์กด ๋ชจ๋์ ํ์
์ ์ถ๊ฐํ๋ ๋ฐ ์ฌ์ฉ๋๋ ํน์ํ๋ ํํ์ ๋ชจ๋ ์ ์ธ์
๋๋ค. ์๋ฌด๊ฒ๋ ์๋ ๋ชจ๋์ ๋ํ ํ์
์ ์์ฑํ๋ ์ฐ๋น์ธํธ ๋ชจ๋ ์ ์ธ๊ณผ ๋ฌ๋ฆฌ, ์ฆ๊ฐ์ ์ด๋ฏธ ํ์
์ ์๊ฐ ์๋ ๋ชจ๋(์์ฒด .d.ts ํ์ผ ๋๋ @types ํจํค์ง์์)์ ํ์ฅํฉ๋๋ค.
๋ชจ๋ ์ฆ๊ฐ์ ์ฌ์ฉํด์ผ ํ๋ ๊ฒฝ์ฐ
๋ชจ๋ ์ฆ๊ฐ์ ๋ค์๊ณผ ๊ฐ์ ๊ฒฝ์ฐ์ ์ด์์ ์ธ ์๋ฃจ์ ์ ๋๋ค:
- ์๋ํํฐ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ํ์
ํ์ฅ: ์ฌ์ฉ ์ค์ธ ์๋ํํฐ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ํ์
์ ์ฌ์ฉ์ ์ง์ ์์ฑ, ๋ฉ์๋ ๋๋ ์ธํฐํ์ด์ค๋ฅผ ์ถ๊ฐํด์ผ ํ๋ ๊ฒฝ์ฐ(์: Express.js
Request๊ฐ์ฒด์ ์ฌ์ฉ์ ์ง์ ์์ฑ ์ถ๊ฐ ๋๋ React ์ปดํฌ๋ํธ์ props์ ์ ๋ฉ์๋ ์ถ๊ฐ). - ์์ฒด ๋ชจ๋์ ์ถ๊ฐ: ๋ ์ผ๋ฐ์ ์ด์ง๋ง, ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ค๋ฅธ ๋ถ๋ถ์์ ์์ฑ์ ๋์ ์ผ๋ก ์ถ๊ฐํด์ผ ํ๋ ๊ฒฝ์ฐ ์์ฒด ๋ชจ๋์ ํ์ ์ ์ฆ๊ฐํ ์ ์์ต๋๋ค. ๊ทธ๋ฌ๋ ์ด๋ ์ข ์ข ๋ฆฌํฉํ ๋ง๋ ์ ์๋ ์ ์ฌ์ ์ธ ๋์์ธ ํจํด์ ๋ํ๋ ๋๋ค.
๊ตฌ๋ฌธ ๋ฐ ๊ตฌ์กฐ
๋ชจ๋ ์ฆ๊ฐ์ ์ฐ๋น์ธํธ ๋ชจ๋๊ณผ ๋์ผํ declare module 'module-name' { ... } ๊ตฌ๋ฌธ์ ์ฌ์ฉํ์ง๋ง, TypeScript๋ ๋ชจ๋ ์ด๋ฆ์ด ์ผ์นํ๋ฉด ์ด๋ฌํ ์ ์ธ์ ๊ธฐ์กด ์ ์ธ๊ณผ ์ง๋ฅ์ ์ผ๋ก ๋ณํฉํฉ๋๋ค. ์ผ๋ฐ์ ์ผ๋ก ์ฌ๋ฐ๋ฅด๊ฒ ์๋ํ๋ ค๋ฉด ๋ชจ๋ ํ์ผ ์์ฒด ๋ด์ ์์ด์ผ ํ๋ฉฐ, ์ข
์ข
๋น export {} ๋๋ ์ค์ import๋ฅผ ํ์๋ก ํฉ๋๋ค.
// express.d.ts (or any .ts file that's part of a module)
import 'express'; // This is crucial to make the augmentation work for 'express'
declare module 'express' {
interface Request {
user?: { // Augmenting the existing Request interface
id: string;
email: string;
roles: string[];
};
organizationId?: string;
// You can also add new functions to the Express Request object
isAuthenticated(): boolean;
}
// You can also augment other interfaces/types from the module
// interface Response {
// sendJson(data: object): Response;
// }
}
์ค์ฉ์ ์ธ ์์ : Express.js Request ๊ฐ์ฒด ์ฆ๊ฐ
Express.js๋ก ๊ตฌ์ถ๋ ์ผ๋ฐ์ ์ธ ์น ์ ํ๋ฆฌ์ผ์ด์
์์๋ ์ฌ์ฉ์๋ฅผ ์ธ์ฆํ๊ณ ํด๋น ์ ๋ณด๋ฅผ req (Request) ๊ฐ์ฒด์ ์ฒจ๋ถํ๋ ๋ฏธ๋ค์จ์ด๋ฅผ ๊ฐ์ง ์ ์์ต๋๋ค. ๊ธฐ๋ณธ์ ์ผ๋ก Express ํ์
์ ์ด ์ฌ์ฉ์ ์ง์ user ์์ฑ์ ๋ํด ์์ง ๋ชปํฉ๋๋ค. ๋ชจ๋ ์ฆ๊ฐ์ ํตํด ์ด๋ฅผ ์์ ํ๊ฒ ์ ์ธํ ์ ์์ต๋๋ค.
๋จผ์ , Express ํ์
์ด ์ค์น๋์ด ์๋์ง ํ์ธํ์ญ์์ค: npm install express @types/express.
์๋ฅผ ๋ค์ด, src/types/express.d.ts์ ๊ฐ์ ์ ์ธ ํ์ผ์ ์์ฑํฉ๋๋ค:
// src/types/express.d.ts
// It's crucial to import the module you are augmenting.
// This ensures TypeScript knows which module's types to extend.
import 'express';
declare module 'express' {
// Augment the Request interface from the 'express' module
interface Request {
user?: {
id: string;
email: string;
firstName: string;
lastName: string;
permissions: string[];
locale: string; // Relevant for global applications
};
requestStartTime?: Date; // Custom property added by logging middleware
// Other custom properties can be added here
}
}
์ด์ TypeScript Express ์ ํ๋ฆฌ์ผ์ด์
์ user ๋ฐ requestStartTime ์์ฑ์ ํ์
์์ ํ๊ฒ ์ฌ์ฉํ ์ ์์ต๋๋ค:
import express, { Request, Response, NextFunction } from 'express';
const app = express();
// Middleware to attach user information
app.use((req: Request, res: Response, next: NextFunction) => {
// Simulate authentication and user attachment
req.user = {
id: 'user-123',
email: 'john.doe@example.com',
firstName: 'John',
lastName: 'Doe',
permissions: ['read', 'write'],
locale: 'en-US'
};
req.requestStartTime = new Date();
next();
});
app.get('/profile', (req: Request, res: Response) => {
if (req.user) {
res.json({
userId: req.user.id,
userEmail: req.user.email,
userLocale: req.user.locale, // Accessing custom locale property
requestTime: req.requestStartTime?.toISOString() // Optional chaining for safety
});
} else {
res.status(401).send('Unauthorized');
}
});
// TypeScript will now correctly type-check access to req.user:
// app.get('/admin', (req: Request, res: Response) => {
// if (req.user && req.user.permissions.includes('admin')) { ... }
// });
app.listen(3000, () => {
console.log('Server running on port 3000');
});
๋ชจ๋ ์ฆ๊ฐ์ ์ฃผ์ ๊ณ ๋ ค ์ฌํญ
- Import ๋ฌธ: ๋ชจ๋ ์ฆ๊ฐ์ ๊ฐ์ฅ ์ค์ํ ์ธก๋ฉด์ ์ ์ธ ํ์ผ ๋ด์ ๋ช
์์ ์ธ
import 'module-name';๋ฌธ์ ๋๋ค. ์ด ์์ผ๋ฉด TypeScript๋ ๊ธฐ์กด ๋ชจ๋์ ์ฆ๊ฐ์ด ์๋ ์ฐ๋น์ธํธ ๋ชจ๋ ์ ์ธ์ผ๋ก ์ฒ๋ฆฌํ ์ ์์ต๋๋ค. - ํน์ ์ฑ: ์ฆ๊ฐ์ ๋์ ๋ชจ๋์ ํนํ๋์ด ์์ผ๋ฏ๋ก ๋ผ์ด๋ธ๋ฌ๋ฆฌ ํ์ ์ ํ์ฅํ๋ ๋ฐ ์ ์ญ ํ์ ์ ์๋ณด๋ค ์์ ํฉ๋๋ค.
- ์๋น์์ ๋ํ ์ํฅ: ์ฆ๊ฐ๋ ํ์ ์ ์ฌ์ฉํ๋ ๋ชจ๋ ํ๋ก์ ํธ๋ ์ถ๊ฐ๋ ํ์ ์์ ์ฑ์ผ๋ก๋ถํฐ ์ด์ ์ ์ป์ผ๋ฉฐ, ์ด๋ ๋ค๋ฅธ ํ์ด ๊ฐ๋ฐํ ๊ณต์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ๋๋ ๋ง์ดํฌ๋ก์๋น์ค์ ๋งค์ฐ ์ ์ฉํฉ๋๋ค.
- ์ถฉ๋ ๋ฐฉ์ง: ๋์ผํ ๋ชจ๋์ ๋ํด ์ฌ๋ฌ ์ฆ๊ฐ์ด ์กด์ฌํ๋ ๊ฒฝ์ฐ, TypeScript๋ ์ด๋ฅผ ๋ณํฉํฉ๋๋ค. ์ด๋ฌํ ์ฆ๊ฐ์ด ํธํ ๊ฐ๋ฅํ๊ณ ์ถฉ๋ํ๋ ์์ฑ ์ ์๋ฅผ ๋์ ํ์ง ์๋์ง ํ์ธํ์ญ์์ค.
๊ธ๋ก๋ฒ ํ ๋ฐ ๋๊ท๋ชจ ์ฝ๋๋ฒ ์ด์ค๋ฅผ ์ํ ๋ชจ๋ฒ ์ฌ๋ก
๊ธ๋ก๋ฒ ํ๊ณผ ๊ด๋ฒ์ํ ์ฝ๋๋ฒ ์ด์ค๋ก ์ด์๋๋ ์กฐ์ง์ ๊ฒฝ์ฐ, ํ์ ์ ์ธ์ ๋ํ ์ผ๊ด๋๊ณ ์ฒด๊ณ์ ์ธ ์ ๊ทผ ๋ฐฉ์์ ์ฑํํ๋ ๊ฒ์ด ๊ฐ์ฅ ์ค์ํฉ๋๋ค. ์ด๋ฌํ ๋ชจ๋ฒ ์ฌ๋ก๋ ๋ณต์ก์ฑ์ ์ต์ํํ๊ณ TypeScript์ ํ์ ์์คํ ์ ์ด์ ์ ๊ทน๋ํํ๋ ๋ฐ ๋์์ด ๋ฉ๋๋ค.
1. ์ ์ญ ์ฌ์ฉ ์ต์ํ, ๋ชจ๋์ฑ ์ ํธ
๊ฐ๋ฅํ๋ฉด ํญ์ ์ ์ญ ํ์ ์ ์๋ณด๋ค ๋ช ์์ ์ธ ๋ชจ๋ import๋ฅผ ์ ํธํ์ญ์์ค. ์ ์ญ ์ ์ธ์ ํน์ ์๋๋ฆฌ์ค์์๋ ํธ๋ฆฌํ์ง๋ง, ํ์ ์ถฉ๋, ์ถ์ ํ๊ธฐ ์ด๋ ค์ด ์์กด์ฑ, ๋ค์ํ ํ๋ก์ ํธ ๊ฐ์ ์ฌ์ฌ์ฉ์ฑ ๊ฐ์๋ก ์ด์ด์ง ์ ์์ต๋๋ค. ๋ช ์์ ์ธ import๋ ํ์ ์ ์ถ์ฒ๋ฅผ ๋ช ํํ ํ์ฌ ๋ค์ํ ์ง์ญ์ ๊ฐ๋ฐ์๊ฐ ์ฝ๊ธฐ ์ฝ๊ณ ์ ์ง๋ณด์์ฑ์ ํฅ์์ํต๋๋ค.
2. .d.ts ํ์ผ์ ์ฒด๊ณ์ ์ผ๋ก ์ ๋ฆฌ
- ์ ์ฉ ๋๋ ํฐ๋ฆฌ: ํ๋ก์ ํธ ๋ฃจํธ์ ์ ์ฉ
src/types/๋๋types/๋๋ ํฐ๋ฆฌ๋ฅผ ์์ฑํ์ญ์์ค. ์ด๋ ๊ฒ ํ๋ฉด ๋ชจ๋ ์ฌ์ฉ์ ์ง์ ํ์ ์ ์ธ์ด ํ ๊ณณ์ ๋ชจ์ฌ ๊ฒ์ํ๊ธฐ ์ฝ์ต๋๋ค. - ๋ช
ํํ ๋ช
๋ช
๊ท์น: ์ ์ธ ํ์ผ์ ์ค๋ช
์ ์ธ ์ด๋ฆ์ ์ฌ์ฉํ์ญ์์ค. ์ฐ๋น์ธํธ ๋ชจ๋์ ๊ฒฝ์ฐ ๋ชจ๋ ์ด๋ฆ(์:
d3-legacy-charts.d.ts)์ ๋ฐ๋ฆ ๋๋ค. ์ ์ญ ํ์ ์ ๊ฒฝ์ฐglobal.d.ts๋๋augmentations.d.ts์ ๊ฐ์ ์ผ๋ฐ์ ์ธ ์ด๋ฆ์ด ์ ์ ํฉ๋๋ค. tsconfig.json๊ตฌ์ฑ:tsconfig.json์ด ์ด๋ฌํ ๋๋ ํฐ๋ฆฌ๋ฅผtypeRoots(์ ์ญ ์ฐ๋น์ธํธ ๋ชจ๋์ ๊ฒฝ์ฐ) ๋ฐinclude(๋ชจ๋ ์ ์ธ ํ์ผ์ ๊ฒฝ์ฐ)์ ์ฌ๋ฐ๋ฅด๊ฒ ํฌํจํ์ฌ TypeScript ์ปดํ์ผ๋ฌ๊ฐ ์ด๋ฅผ ์ฐพ์ ์ ์๋๋ก ํ์ญ์์ค. ์๋ฅผ ๋ค์ด:{ "compilerOptions": { // ... "typeRoots": [ "./node_modules/@types", "./src/types" ], "moduleResolution": "node" }, "include": [ "src/**/*.ts", "src/**/*.tsx", "src/**/*.d.ts" ] }
3. ๊ธฐ์กด @types ํจํค์ง ์ฐ์ ํ์ฉ
์๋ํํฐ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๋ํ ์ฌ์ฉ์ ์ง์ .d.ts ํ์ผ์ ์์ฑํ๊ธฐ ์ ์ ํญ์ npm์ @types/{library-name} ํจํค์ง๊ฐ ์๋์ง ํ์ธํ์ญ์์ค. ์ด ํจํค์ง๋ ์ข
์ข
์ปค๋ฎค๋ํฐ์์ ์ ์ง ๊ด๋ฆฌ๋๊ณ ํฌ๊ด์ ์ด๋ฉฐ ์ต์ ์ํ๋ก ์ ์ง๋๋ฏ๋ก ํ์ ๋
ธ๋ ฅ์ ํฌ๊ฒ ์ ์ฝํ๊ณ ์ ์ฌ์ ์ธ ์ค๋ฅ๋ฅผ ์ค์ผ ์ ์์ต๋๋ค.
4. ์ฌ์ฉ์ ์ง์ ํ์ ์ ์ธ ๋ฌธ์ํ
๋ชจ๋ ์ฌ์ฉ์ ์ง์ .d.ts ํ์ผ์ ๊ทธ ๋ชฉ์ , ์ ์ธ ๋ด์ฉ, ํ์์ฑ์ ๋ช
ํํ๊ฒ ์ค๋ช
ํ๋ ์ฃผ์์ ์ ๊ณตํ์ญ์์ค. ์ด๋ ์ ์ญ์ ์ผ๋ก ์ก์ธ์ค ๊ฐ๋ฅํ ํ์
์ด๋ ๋ณต์กํ ์ฐ๋น์ธํธ ๋ชจ๋ ์ ์ธ์ ํนํ ์ค์ํ๋ฉฐ, ์๋ก์ด ํ ๊ตฌ์ฑ์์ด ์์คํ
์ ๋ ๋นจ๋ฆฌ ์ดํดํ๊ณ ํฅํ ๊ฐ๋ฐ ์ฃผ๊ธฐ ๋์ ์ฐ๋ฐ์ ์ธ ์์์ ๋ฐฉ์งํ๋ ๋ฐ ๋์์ด ๋ฉ๋๋ค.
5. ์ฝ๋ ๊ฒํ ํ๋ก์ธ์ค์ ํตํฉ
์ฌ์ฉ์ ์ง์ ํ์ ์ ์ธ์ ์ผ๊ธ ์ฝ๋์ฒ๋ผ ๋ค๋ฃจ์ญ์์ค. ์ ํ๋ฆฌ์ผ์ด์ ๋ก์ง๊ณผ ๋์ผํ ์๊ฒฉํ ์ฝ๋ ๊ฒํ ํ๋ก์ธ์ค๋ฅผ ๊ฑฐ์ณ์ผ ํฉ๋๋ค. ๊ฒํ ์๋ ์ ํ์ฑ, ์์ ์ฑ, ๋ชจ๋ฒ ์ฌ๋ก ์ค์ ๋ฐ ์ํคํ ์ฒ ๊ฒฐ์ ๊ณผ์ ์ผ๊ด์ฑ์ ํ์ธํด์ผ ํฉ๋๋ค.
6. ํ์ ์ ์ ํ ์คํธ
.d.ts ํ์ผ์๋ ๋ฐํ์ ์ฝ๋๊ฐ ํฌํจ๋์ด ์์ง ์์ง๋ง, ๊ทธ ์ ํ์ฑ์ ๋งค์ฐ ์ค์ํฉ๋๋ค. dts-jest์ ๊ฐ์ ๋๊ตฌ๋ฅผ ์ฌ์ฉํ์ฌ "ํ์
ํ
์คํธ"๋ฅผ ์์ฑํ๊ฑฐ๋ ์ ํ๋ฆฌ์ผ์ด์
์ ์๋น์ ์ฝ๋๊ฐ ํ์
์ค๋ฅ ์์ด ์ปดํ์ผ๋๋์ง ํ์ธํ๋ ๊ฒ์ ๊ณ ๋ คํ์ญ์์ค. ์ด๋ ํ์
์ ์ธ์ด ๊ธฐ๋ณธ JavaScript๋ฅผ ์ ํํ๊ฒ ๋ฐ์ํ๋์ง ํ์ธํ๋ ๋ฐ ํ์์ ์
๋๋ค.
7. ๊ตญ์ ํ(i18n) ๋ฐ ํ์งํ(l10n) ์ํฅ ๊ณ ๋ ค
ํ์ ์ ์ธ์ ์ธ๊ฐ ์ธ์ด ์ธก๋ฉด์์๋ ์ธ์ด ๋ ๋ฆฝ์ ์ด์ง๋ง, ๊ธ๋ก๋ฒ ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ฐ๋ฅํ๊ฒ ํ๋ ๋ฐ ์ค์ํ ์ญํ ์ ํฉ๋๋ค:
- ์ผ๊ด๋ ๋ฐ์ดํฐ ๊ตฌ์กฐ: ๊ตญ์ ํ๋ ๋ฌธ์์ด, ๋ ์ง ํ์ ๋๋ ํตํ ๊ฐ์ฒด์ ๋ํ ํ์ ์ด ๋ชจ๋ ๋ชจ๋ ๋ฐ ๋ก์ผ์ผ์์ ๋ช ํํ๊ฒ ์ ์๋๊ณ ์ผ๊ด๋๊ฒ ์ฌ์ฉ๋๋์ง ํ์ธํ์ญ์์ค.
- ํ์งํ ๊ณต๊ธ์: ์ ํ๋ฆฌ์ผ์ด์
์ด ์ ์ญ ํ์งํ ๊ณต๊ธ์๋ฅผ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ, ํด๋น ํ์
(์:
window.i18n.translate('key'))์ด ์ ์ ํ๊ฒ ์ ์ธ๋์ด์ผ ํฉ๋๋ค. - ๋ก์ผ์ผ๋ณ ๋ฐ์ดํฐ: ํ์ ์ ๋ก์ผ์ผ๋ณ ๋ฐ์ดํฐ ๊ตฌ์กฐ(์: ์ฃผ์ ํ์)๊ฐ ์ฌ๋ฐ๋ฅด๊ฒ ์ฒ๋ฆฌ๋๋๋ก ํ์ฌ ๋ค๋ฅธ ์ง์ญ์ ๋ฐ์ดํฐ๋ฅผ ํตํฉํ ๋ ์ค๋ฅ๋ฅผ ์ค์ด๋ ๋ฐ ๋์์ด ๋ ์ ์์ต๋๋ค.
์ผ๋ฐ์ ์ธ ํจ์ ๊ณผ ๋ฌธ์ ํด๊ฒฐ
์ธ์ฌํ ๊ณํ์๋ ๋ถ๊ตฌํ๊ณ ํ์ ์ ์ธ ์์ ์ ๋๋๋ก ์ด๋ ค์์ ์ด๋ํ ์ ์์ต๋๋ค. ๋ค์์ ๋ช ๊ฐ์ง ์ผ๋ฐ์ ์ธ ํจ์ ๊ณผ ๋ฌธ์ ํด๊ฒฐ์ ์ํ ํ์ ๋๋ค:
- "Cannot find module 'X'" ๋๋ "Cannot find name 'Y'":
- ๋ชจ๋์ ๊ฒฝ์ฐ: ์ฐ๋น์ธํธ ๋ชจ๋ ์ ์ธ ๋ฌธ์์ด(์:
'my-library')์ดimport๋ฌธ์ ์๋ ๊ฒ๊ณผ ์ ํํ ์ผ์นํ๋์ง ํ์ธํ์ญ์์ค. - ์ ์ญ ํ์
์ ๊ฒฝ์ฐ:
.d.tsํ์ผ์ดtsconfig.json์include๋ฐฐ์ด์ ํฌํจ๋์ด ์๊ณ , ์ ์ญ ์ฐ๋น์ธํธ ํ์ผ์ธ ๊ฒฝ์ฐ ํด๋น ํฌํจ ๋๋ ํฐ๋ฆฌ๊ฐtypeRoots์ ์๋์ง ํ์ธํ์ญ์์ค. tsconfig.json์moduleResolution์ค์ ์ด ํ๋ก์ ํธ์ ์ ํฉํ์ง(์ผ๋ฐ์ ์ผ๋ก"node") ํ์ธํ์ญ์์ค.
- ๋ชจ๋์ ๊ฒฝ์ฐ: ์ฐ๋น์ธํธ ๋ชจ๋ ์ ์ธ ๋ฌธ์์ด(์:
- ์ ์ญ ๋ณ์ ์ถฉ๋: ์ ์ญ ํ์
(์:
var MY_GLOBAL)์ ์ ์ํ๊ณ ๋ค๋ฅธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ๋๋ ์ฝ๋์ ์ผ๋ถ๊ฐ ๋์ผํ ์ด๋ฆ์ผ๋ก ๋ฌด์ธ๊ฐ๋ฅผ ์ ์ธํ๋ฉด ์ถฉ๋์ด ๋ฐ์ํฉ๋๋ค. ์ด๋ ์ ์ญ์ ๋๋ฌผ๊ฒ ์ฌ์ฉํ๋ผ๋ ์กฐ์ธ์ ๋ค์ ํ๋ฒ ๊ฐ์กฐํฉ๋๋ค. declare global์ ๋ํexport {}๋๋ฝ:.d.tsํ์ผ์ ์ ์ญ ์ ์ธ๋ง ์๊ณimport๋๋export๊ฐ ์์ผ๋ฉด TypeScript๋ ์ด๋ฅผ "์คํฌ๋ฆฝํธ ํ์ผ"๋ก ์ฒ๋ฆฌํ๊ณ ๊ทธ ๋ด์ฉ์declare global๋ํผ ์์ด ์ ์ญ์ ์ผ๋ก ์ฌ์ฉ ๊ฐ๋ฅํฉ๋๋ค. ์๋ํ ์ ์์ง๋ง,export {}๋ฅผ ๋ช ์์ ์ผ๋ก ์ฌ์ฉํ๋ฉด ๋ชจ๋์ด ๋์ดdeclare global์ด ๋ชจ๋ ์ปจํ ์คํธ ๋ด์์ ์ ์ญ ์ค์ฝํ๋ฅผ ์ฆ๊ฐํ๋ ค๋ ์๋๋ฅผ ๋ช ํํ๊ฒ ๋ช ์ํ ์ ์์ต๋๋ค.- ๊ฒน์น๋ ์ฐ๋น์ธํธ ์ ์ธ: ์๋ก ๋ค๋ฅธ
.d.tsํ์ผ์ ๋์ผํ ๋ชจ๋ ๋ฌธ์์ด์ ๋ํ ์ฌ๋ฌ ์ฐ๋น์ธํธ ๋ชจ๋ ์ ์ธ์ด ์๋ ๊ฒฝ์ฐ TypeScript๋ ์ด๋ฅผ ๋ณํฉํฉ๋๋ค. ์ผ๋ฐ์ ์ผ๋ก ์ ์ตํ์ง๋ง, ์ ์ธ์ด ํธํ๋์ง ์์ผ๋ฉด ๋ฌธ์ ๊ฐ ๋ฐ์ํ ์ ์์ต๋๋ค. - IDE๊ฐ ํ์
์ ์ธ์ํ์ง ๋ชปํจ: ์
.d.tsํ์ผ์ ์ถ๊ฐํ๊ฑฐ๋tsconfig.json์ ์์ ํ ํ, ๋๋๋ก IDE(VS Code์ ๊ฐ์)๋ TypeScript ์ธ์ด ์๋ฒ๋ฅผ ๋ค์ ์์ํด์ผ ํฉ๋๋ค.
๊ฒฐ๋ก
์ฐ๋น์ธํธ ๋ชจ๋, ์ ์ญ ํ์ ์ ์, ๋ชจ๋ ์ฆ๊ฐ์ ํฌํจํ๋ TypeScript์ ๋ชจ๋ ์ ์ธ ๊ธฐ๋ฅ์ ๊ฐ๋ฐ์๊ฐ TypeScript๋ฅผ ๊ธฐ์กด JavaScript ์์ฝ์์คํ ๊ณผ ์ํํ๊ฒ ํตํฉํ๊ณ ์ฌ์ฉ์ ์ง์ ํ์ ์ ์ ์ํ ์ ์๋๋ก ํ๋ ๊ฐ๋ ฅํ ๊ธฐ๋ฅ์ ๋๋ค. ๋ณต์กํ ์ํํธ์จ์ด๋ฅผ ๊ตฌ์ถํ๋ ๊ธ๋ก๋ฒ ํ์๊ฒ ์ด๋ฌํ ๊ฐ๋ ์ ๋ง์คํฐํ๋ ๊ฒ์ ๋จ์ํ ํ๋ฌธ์ ์ธ ์ฐ์ต์ด ์๋๋ผ, ๊ฒฌ๊ณ ํ๊ณ ํ์ฅ ๊ฐ๋ฅํ๋ฉฐ ์ ์ง๋ณด์ ๊ฐ๋ฅํ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ ๊ณตํ๊ธฐ ์ํ ์ค์ ์ ์ธ ํ์ ์์์ ๋๋ค.
์ฐ๋น์ธํธ ๋ชจ๋ ์ ์ธ์ ์์ฒด ํ์
์ ์๊ฐ ์๋ ์ธ๋ถ JavaScript ๋ชจ๋์ ์ค๋ช
ํ์ฌ ์ฝ๋ ๋ฐ ๋น์ฝ๋ ์์ฐ ๋ชจ๋์ ๋ํด ํ์
์์ ํ import๋ฅผ ๊ฐ๋ฅํ๊ฒ ํ๋ ๋ฐ ์ฃผ๋ก ์ฌ์ฉ๋ฉ๋๋ค. ์ ์ญ ํ์
์ ์๋ ๋์ฑ ์ ์คํ๊ฒ ์ฌ์ฉ๋๋ฉฐ, ์ ์ญ ์ค์ฝํ๋ฅผ ํ์ฅํ๊ณ ๋ธ๋ผ์ฐ์ window ๊ฐ์ฒด ๋๋ ๊ธฐ๋ณธ ํ๋กํ ํ์
์ ์ฆ๊ฐํ ์ ์์ต๋๋ค. ๋ชจ๋ ์ฆ๊ฐ์ Express.js์ ๊ฐ์ด ๋๋ฆฌ ์ฌ์ฉ๋๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ํ์
์์ ์ฑ์ ํฅ์์ํค๋ฉด์ ๊ธฐ์กด ๋ชจ๋ ์ ์ธ์ ์ถ๊ฐํ๋ ์ ๊ตํ ๋ฐฉ๋ฒ์ ์ ๊ณตํฉ๋๋ค.
๋ชจ๋์ฑ ์ฐ์ , ์ ์ธ ํ์ผ ์ ๋ฆฌ, ๊ณต์ @types ํ์ฉ, ์ฌ์ฉ์ ์ง์ ํ์
์ฒ ์ ํ ๋ฌธ์ํ์ ๊ฐ์ ๋ชจ๋ฒ ์ฌ๋ก๋ฅผ ์ค์ํจ์ผ๋ก์จ ํ์ TypeScript์ ๋ชจ๋ ๊ธฐ๋ฅ์ ํ์ฉํ ์ ์์ต๋๋ค. ์ด๋ ๋ฒ๊ทธ ๊ฐ์, ์ฝ๋ ๋ช
ํ์ฑ ํฅ์, ๋ค์ํ ์ง๋ฆฌ์ ์์น ๋ฐ ๊ธฐ์ ์ ๋ฐฐ๊ฒฝ์ ๊ฐ์ง ํ ๊ฐ์ ํจ์จ์ ์ธ ํ์
์ผ๋ก ์ด์ด์ ธ ๊ถ๊ทน์ ์ผ๋ก ๋์ฑ ํ๋ ฅ์ ์ด๊ณ ์ฑ๊ณต์ ์ธ ์ํํธ์จ์ด ๊ฐ๋ฐ ์๋ช
์ฃผ๊ธฐ๋ฅผ ์ด์งํ ๊ฒ์
๋๋ค. ์ด๋ฌํ ๋๊ตฌ๋ฅผ ๋ฐ์๋ค์ด๊ณ , ๋นํ ๋ฐ ์๋ ํ์
์์ ์ฑ๊ณผ ๋ช
ํ์ฑ์ผ๋ก ๊ธ๋ก๋ฒ ๊ฐ๋ฐ ๋
ธ๋ ฅ์ ๊ฐํํ์ญ์์ค.